package com.casic.modules.activiti.service;

import com.casic.modules.activiti.util.JqGridPageView;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ModelQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author htkjsx
 * @version 2016年5月20日 下午3:16:07
 */
@Service
public class ActModelService  {
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private ProcessEngine processEngine;
	
	protected ObjectMapper objectMapper = new ObjectMapper();
	/**
	 * 
	 * @Title getActModelList
	 * @Description (查询模型列表)
	 * @author 颜金星
	 * @create 2017年4月21日-下午5:29:55
	 * @Param @param params
	 * @Param @return
	 * @return PageInfo<org.activiti.engine.repository.Model>
	 * @throws
	 */
	public JqGridPageView<Model> getActModelList(Map<String, Object> params) {
	    JqGridPageView<Model> gridView = new JqGridPageView<Model>();
	    int firstResult = 1;
    	int maxResults = 10;
    	String name=null;
    	if(params.get("page")!=null){
    		firstResult=Integer.parseInt((String)params.get("page"));
    	}
    	if(params.get("rows")!=null){
    		maxResults = (Integer)params.get("rows");
    	}
		if(params.get("queryname")!=null){
			name = (String)params.get("queryname");
		}
    	//String modelCategory=(String)params.get("modelCategory");
		ModelQuery modelQuery=null;
		if(name!=null){
			 modelQuery = repositoryService.createModelQuery().modelNameLike(name).latestVersion().orderByLastUpdateTime().desc();

		}
		else{
			 modelQuery = repositoryService.createModelQuery().latestVersion().orderByLastUpdateTime().desc();
		}
	   gridView.setCurrentPage((firstResult - 1) * maxResults);
		gridView.setMaxResults(maxResults);
		gridView.setRecords(modelQuery.count());
		gridView.setRows(modelQuery.listPage((firstResult - 1)*maxResults, maxResults));
	    return  gridView;
    }
	/**
	 *
	 * @Title createActModel
	 * @Description (创建模型)
	 * @author 颜金星
	 * @create 2017年4月21日-下午5:58:17
	 * @Param @param params
	 * @Param @return
	 * @Param @throws UnsupportedEncodingException
	 * @return Model
	 * @throws
	 */
	public Model createActModel(Map<String, Object> params) throws UnsupportedEncodingException{
		ObjectNode editorNode = objectMapper.createObjectNode();
		editorNode.put("id", "canvas");
		editorNode.put("resourceId", "canvas");
		ObjectNode properties = objectMapper.createObjectNode();
		properties.put("process_author", "航天科技控股集团山西有限公司");
		editorNode.put("properties", properties);
		ObjectNode stencilset = objectMapper.createObjectNode();
		stencilset.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
		editorNode.put("stencilset", stencilset);
		Model modelData = repositoryService.newModel();
		String description = (String)params.get("description");
		modelData.setKey(UUID.randomUUID().toString());
		modelData.setName((String)params.get("name"));
	//	modelData.setCategory((String)params.get("category"));
		modelData.setVersion(Integer.parseInt(String.valueOf(repositoryService.createModelQuery().modelKey(modelData.getKey()).count()+1)));
		ObjectNode modelObjectNode = objectMapper.createObjectNode();
		modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, (String)params.get("name"));
		modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, modelData.getVersion());
		modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
		modelData.setMetaInfo(modelObjectNode.toString());
		repositoryService.saveModel(modelData);
		repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
		return modelData;
	}
	/**
	 * @throws IOException
	 * @throws JsonProcessingException
	 *
	 * @Title deployActModel
	 * @Description (部署流程)
	 * @author 颜金星
	 * @create 2017年4月21日-下午6:17:08
	 * @Param @param id
	 * @Param @return
	 * @return Map<String,String>
	 * @throws
	 */
	public Map<String, String> deployActModel(String id) throws JsonProcessingException, IOException{
		Map<String, String> map=new HashMap<String, String>();
		Model modelData = repositoryService.getModel(id);
		BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
		JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
		BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
		BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
		byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel);
		String processName = modelData.getName();
		processName += ".bpmn20.xml";
		System.out.println("========="+processName+"============"+modelData.getName());
		ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
		Deployment deployment = repositoryService.createDeployment().name(modelData.getName())
				.addInputStream(processName, in).deploy();
//				.addString(processName, new String(bpmnBytes)).deploy();
		// 设置流程分类
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
		for (ProcessDefinition processDefinition : list) {
			repositoryService.setProcessDefinitionCategory(processDefinition.getId(), null);
			map.put("state", "success");
		}
		if (list.size() == 0){
			map.put("state", "error");
			map.put("msg", "没有该流程！！");
		}
        return map;
	}
	/**
	 *
	 * @Title exportActModel
	 * @Description (导出模型)
	 * @author 颜金星
	 * @create 2017年4月21日-下午7:00:22
	 * @Param @param id
	 * @Param @param response
	 * @Param @throws IOException
	 * @return void
	 * @throws
	 */
	public void exportActModel(String id, HttpServletResponse response) throws IOException{
		Model modelData = repositoryService.getModel(id);
		BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
		JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
		BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
		BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
		byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel);
		ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
		IOUtils.copy(in, response.getOutputStream());
		String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml";
		response.setHeader("Content-Disposition", "attachment; filename=" + filename);
		response.flushBuffer();
	}
	/**
	 * 
	 * @Title deleteModel
	 * @Description (删除流程模型)
	 * @author 颜金星
	 * @create 2017年5月26日-下午5:15:18
	 * @Param @param params
	 * @return void
	 * @throws
	 */
	public void deleteModel(Map<String, Object> params){
		String id=(String)params.get("id");
		repositoryService.deleteModel(id);
	}
}
